package com.xinqi.modules.course.course.thread;

import cn.hutool.core.collection.ConcurrentHashSet;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.R;
import com.xinqi.modules.course.chapter.convert.CourseChapterConvert;
import com.xinqi.modules.course.chapter.domain.CourseChapterEntity;
import com.xinqi.modules.course.chapter.service.CourseChapterService;
import com.xinqi.modules.course.textbook.convert.CourseCloudTextbookContentConvert;
import com.xinqi.modules.course.textbook.domain.CourseCloudTextbookContentEntity;
import com.xinqi.modules.course.textbook.manager.CourseCloudTextbookContentManager;
import com.xinqi.modules.sys.textbook.client.CloudTextbookCatalogClient;
import com.xinqi.modules.sys.textbook.client.CloudTextbookContentClient;
import com.xinqi.modules.sys.textbook.dto.rsp.CloudTextbookCatalogResultDTO;
import com.xinqi.modules.sys.textbook.dto.rsp.CloudTextbookContentResultDTO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 拷贝课程内容
 *
 * @author wuwenjie
 */

@Service
@RequiredArgsConstructor
public class CopyCourseContentService {

    @Lazy
    private final CourseChapterConvert courseChapterConvert;
    private final CourseCloudTextbookContentConvert courseCloudTextbookContentConvert;
    private final CourseCloudTextbookContentManager courseCloudTextbookContentManager;
    private final CloudTextbookCatalogClient cloudTextbookCatalogClient;
    private final CloudTextbookContentClient cloudTextbookContentClient;
    private final CourseChapterService chapterService;

    /**
     * 保存云课本目录到章节，保存内容到课堂-云课本内容
     *
     * @param cloudTextbookId
     */


    @Async("threadPoolTaskExecutor")
    @Transactional(rollbackFor = Exception.class)
    public void saveCloudTextbook(Long courseId, List<Long> classIdList, Long cloudTextbookId) {
        if (Objects.isNull(cloudTextbookId)) {
            return;
        }

        // 获取原有章节数据
        List<CourseChapterEntity> oldChapterList = chapterService.maxSortChapterList(classIdList);
        Map<Long, List<CourseChapterEntity>> oldChapterMap = oldChapterList.stream().collect(Collectors.groupingBy(CourseChapterEntity::getClassId));


        List<CloudTextbookCatalogResultDTO> cloudTextbookCatalogTreeList = R.as(cloudTextbookCatalogClient.tree(cloudTextbookId));
        List<CloudTextbookContentResultDTO> cloudTextbookContentResultList = R.as(cloudTextbookContentClient.findByCloudTextbookId(cloudTextbookId));

        CommonErrors.BAD_REQUEST.check(CollectionUtils.isNotEmpty(cloudTextbookCatalogTreeList), "章节不能为空");
        CommonErrors.BAD_REQUEST.check(CollectionUtils.isNotEmpty(cloudTextbookContentResultList), "内容不能为空");

        Set<CourseChapterEntity> unSavedChapterSet = new ConcurrentHashSet<>();
        Set<CourseCloudTextbookContentEntity> unSavedTextbookSet = new ConcurrentHashSet<>();

        //组装目录/章节数据，章节和班级强绑定
        for (Long classId : classIdList) {
            Integer sort = 1;
            // 获取原有的章节排序最大值
            if (Objects.nonNull(oldChapterMap.get(classId))) {
                CourseChapterEntity oldChapter = oldChapterMap.get(classId).get(0);
                sort = oldChapter.getSort();
            }
            for (CloudTextbookCatalogResultDTO parent : cloudTextbookCatalogTreeList) {
                // 设置parent的排序值
                parent.setSort(sort++);
                //保存父
                CourseChapterEntity parentEntity = this.copyChapter(courseId, classId, 0L, parent, cloudTextbookContentResultList.stream().map(CloudTextbookContentResultDTO::getRefId).collect(Collectors.toSet()));
                unSavedChapterSet.add(parentEntity);
                Set<CourseCloudTextbookContentEntity> fatherTextSet = this.copyContent(parent.getId(), parentEntity.getId(), cloudTextbookContentResultList);

                //递归保存子和孙，这里采用异步方式实现
                this.recursionCopy(courseId, classId, parentEntity.getId(), parent, cloudTextbookContentResultList, unSavedChapterSet, fatherTextSet);
                unSavedTextbookSet.addAll(fatherTextSet);
            }
        }

        //统一保存章节
        if (CollectionUtils.isNotEmpty(unSavedChapterSet)) {
            chapterService.saveBatch(unSavedChapterSet);
        }

        //统一保存云课本内容
        if (CollectionUtils.isNotEmpty(unSavedTextbookSet)) {
            courseCloudTextbookContentManager.saveBatch(unSavedTextbookSet);
        }
    }

    public void recursionCopy(Long courseId, Long classId, Long parentId, CloudTextbookCatalogResultDTO parent, List<CloudTextbookContentResultDTO> cloudTextbookContentResultList, Set<CourseChapterEntity> unSavedChapterSet, Set<CourseCloudTextbookContentEntity> unSavedTextBookSet) {
        if (CollectionUtils.isNotEmpty(parent.getChildren())) {
            Set<Long> refIdSet = cloudTextbookContentResultList.stream().map(CloudTextbookContentResultDTO::getRefId).collect(Collectors.toSet());

            for (CloudTextbookCatalogResultDTO son : parent.getChildren()) {
                CourseChapterEntity chapterEntity = this.copyChapter(courseId, classId, parentId, son, refIdSet);
                unSavedChapterSet.add(chapterEntity);

                Set<CourseCloudTextbookContentEntity> sonSet = this.copyContent(son.getId(), chapterEntity.getId(), cloudTextbookContentResultList);

                if (CollectionUtils.isNotEmpty(sonSet)) {
                    unSavedTextBookSet.addAll(sonSet);
                }

                // 并行递归处理子节点
                recursionCopy(courseId, classId, chapterEntity.getId(), son, cloudTextbookContentResultList, unSavedChapterSet, unSavedTextBookSet);
            }
        }
    }

    /**
     * 拷贝目录，这里不能动，不允许频繁查最大值，否则创建课程性能会下降到10s/次，章节排序有问题请使用 is_cloud_textbook_catalog 字段进去区分，不允许牺牲性能兼顾排序。
     *
     * @param courseId 课程id
     * @param classId  班级id
     * @param parentId 需要挂接的父id
     * @param catalog  源目录
     * @return 生成的目录
     */

    public CourseChapterEntity copyChapter(Long courseId, Long classId, Long parentId, CloudTextbookCatalogResultDTO catalog, Set<Long> refIdSet) {
        return courseChapterConvert.changeChapter(courseId, classId, parentId, catalog, refIdSet);
    }


    /**
     * 拷贝云课本课堂内容
     *
     * @param originalRefId 源目录id
     * @param targetRefId   需要关联的新的章节id
     * @param contentList   源内容列表
     */

    public Set<CourseCloudTextbookContentEntity> copyContent(Long originalRefId, Long targetRefId, List<CloudTextbookContentResultDTO> contentList) {
        Set<CloudTextbookContentResultDTO> refContentSet = contentList.stream().filter(content -> Objects.equals(content.getRefId(), originalRefId)).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(refContentSet)) {
            return new ConcurrentHashSet<>();
        }
        //为每个entity预制id，后面统一保存
        return refContentSet.stream().map(content -> courseCloudTextbookContentConvert.changeContent(content, targetRefId)).collect(Collectors.toSet());
    }

}

